/*----------------------------------------------------------------------------*/
/* Copyright 2016-2020,2022                                                   */
/*                                                                            */
/* NXP Confidential. This software is owned or controlled by NXP and may only */
/* be used strictly in accordance with the applicable license terms.          */
/* By expressly accepting such terms or by downloading, installing,           */
/* activating and/or otherwise using the software, you are agreeing that you  */
/* have read, and that you agree to comply with and are bound by, such        */
/* license terms. If you do not agree to be bound by the applicable license   */
/* terms, then you may not retain, install, activate or otherwise use the     */
/* software.                                                                  */
/*----------------------------------------------------------------------------*/

/** \file
* Example Source abstracting component data structure and code initialization and code specific to HW used in the examples
* This file shall be present in all examples. A customer does not need to touch/modify this file. This file
* purely depends on the phNxpBuild_Lpc.h or phNxpBuild_App.h
* The phAppInit.h externs the component data structures initialized here that is in turn included by the core examples.
* The core example shall not use any other variable defined here except the RdLib component data structures(as explained above)
* The RdLib component initialization requires some user defined data and function pointers.
* These are defined in the respective examples and externed here.
*
* Keystore and Crypto initialization needs to be handled by application.
*
* $Author: jenkins_ cm (nxp92197) $
* $Revision: 4184 $
* $Date: 2016-01-22 18:04:59 +0530 (Fri, 22 Jan 2016) $
*
* History:
* BK: Generated 25. Sept 2014
*
*/

/* Status header */
#include <ph_Status.h>

#include "phApp_Init.h"

/* LLCP header */
#include <phlnLlcp.h>

#include <phOsal.h>

#include <phDriver.h>

#ifdef PH_PLATFORM_HAS_ICFRONTEND
#include "BoardSelection.h"
#endif /* PH_PLATFORM_HAS_ICFRONTEND */

#ifdef PHDRIVER_KINETIS_K82
#include <fsl_port.h>
#include <fsl_pit.h>
#ifdef DEBUG
#include <fsl_clock.h>
#endif /* DEBUG */
#endif /* PHDRIVER_KINETIS_K82 */

/* HAL specific headers */
#include <phhalHw_Pn5190_Instr.h>

#ifdef PHDRIVER_KINETIS_K82
#ifdef DEBUG

#define KINETIS_K82_DEBUG_UART_CLK_FREQ         CLOCK_GetOsc0ErClkFreq()
#define KINETIS_K82_DEBUG_UART_BASEADDR        (uint32_t)(LPUART4)
#define KINETIS_K82_DEBUG_UART_INSTANCE        4U
#define KINETIS_K82_DEBUG_UART_BAUDRATE         115200
#define KINETIS_K82_DEBUG_UART_TYPE             DEBUG_CONSOLE_DEVICE_TYPE_LPUART

#endif /* DEBUG */

/*! @brief Clock configuration structure. */
typedef struct _clock_config
{
    mcg_config_t mcgConfig;       /*!< MCG configuration.      */
    sim_clock_config_t simConfig; /*!< SIM configuration.      */
    osc_config_t oscConfig;       /*!< OSC configuration.      */
    uint32_t coreClock;           /*!< core clock frequency.   */
} clock_config_t;
#endif /* PHDRIVER_KINETIS_K82 */

#ifdef PH_OSAL_LINUX
#    define PI_IRQ_POLLING_TASK_PRIO    0
#    define PI_IRQ_POLLING_TASK_STACK   0x20000
     phOsal_ThreadObj_t gphPiThreadObj;
#endif /* PH_OSAL_LINUX */

#if defined(PHDRIVER_LPC1769) && defined(__CC_ARM)
uint32_t SystemCoreClock;
#endif
/*******************************************************************************
**   Function Declarations
*******************************************************************************/
#ifdef PHDRIVER_KINETIS_K82
static void phApp_K82_Init(void);
#endif /* PHDRIVER_KINETIS_K82 */

#ifdef PH_OSAL_LINUX
static void phExample_IrqPolling(void* param);
#endif /* PH_OSAL_LINUX */

phStatus_t phApp_Configure_IRQ(void);

/*******************************************************************************
**   Clock configuration of K82 Platform
*******************************************************************************/

#ifdef PHDRIVER_KINETIS_K82
/* Configuration for enter RUN mode. Core clock = 50MHz. */
const clock_config_t g_defaultClockConfigRun = {
    .mcgConfig =
        {
            .mcgMode = kMCG_ModePEE,             /* Work in PEE mode. */
            .irclkEnableMode = kMCG_IrclkEnable, /* MCGIRCLK enable. */
            .ircs = kMCG_IrcSlow,                /* Select IRC32k. */
            .fcrdiv = 0U,                        /* FCRDIV is 0. */

            .frdiv = 4U,
            .drs = kMCG_DrsLow,         /* Low frequency range. */
            .dmx32 = kMCG_Dmx32Default, /* DCO has a default range of 25%. */
            .oscsel = kMCG_OscselOsc,   /* Select OSC. */

            .pll0Config =
                {
                    .enableMode = 0U, .prdiv = 0x01U, .vdiv = 0x01U,
                },
        },
    .simConfig =
        {
            .pllFllSel = 1U,        /* PLLFLLSEL select PLL. */
            .pllFllDiv = 0U,        /* PLLFLLSEL clock divider divisor. */
            .pllFllFrac = 0U,       /* PLLFLLSEL clock divider fraction. */
            .er32kSrc = 5U,         /* ERCLK32K selection, use RTC. */
            .clkdiv1 = 0x01140000U, /* SIM_CLKDIV1. */
        },
    .oscConfig = {.freq = CPU_XTAL_CLK_HZ,
                  .capLoad = 0,
                  .workMode = kOSC_ModeOscLowPower,
                  .oscerConfig =
                      {
                          .enableMode = kOSC_ErClkEnable,
#if (defined(FSL_FEATURE_OSC_HAS_EXT_REF_CLOCK_DIVIDER) && FSL_FEATURE_OSC_HAS_EXT_REF_CLOCK_DIVIDER)
                          .erclkDiv = 0U,
#endif
                      }},

};
#endif /* PHDRIVER_KINETIS_K82 */

/*******************************************************************************
**   Global Variable Declaration
*******************************************************************************/

#ifdef NXPBUILD__PHLN_LLCP_SW
phlnLlcp_Sw_DataParams_t           slnLlcp;            /* LLCP component */
#endif /* NXPBUILD__PHLN_LLCP_SW */

/* General information bytes to be sent with ATR Request */
#if defined(NXPBUILD__PHPAL_I18092MPI_SW) || defined(NXPBUILD__PHPAL_I18092MT_SW)
uint8_t aLLCPGeneralBytes[36] = { 0x46,0x66,0x6D,
                                  0x01,0x01,0x10,       /*VERSION*/
                                  0x03,0x02,0x00,0x01,  /*WKS*/
                                  0x04,0x01,0xF1        /*LTO*/
                                 };
uint8_t   bLLCPGBLength = 13;
#endif

/* ATR Response or ATS Response holder */
#if defined(NXPBUILD__PHPAL_I14443P4A_SW)     || \
    defined(NXPBUILD__PHPAL_I18092MPI_SW)
uint8_t    aResponseHolder[64];
#endif

/* prints if error is detected */
#define CHECK_SUCCESS(x)              \
    if ((x) != PH_ERR_SUCCESS)        \
{                                     \
    DEBUG_PRINTF("\nLine: %d   Error - (0x%04X) has occurred : 0xCCEE CC-Component ID, EE-Error code. Refer-ph_Status.h\n ", __LINE__, (x)); \
    return (x);                       \
}

/*******************************************************************************
**   Function Definitions
*******************************************************************************/
#ifdef PHDRIVER_KINETIS_K82
static void phApp_K82_Init(void)
{
#ifdef DEBUG
    uint32_t uartClkSrcFreq;
#endif /* DEBUG */

    pit_config_t pitConfig;         /* Structure of initialize PIT */

    CLOCK_SetSimSafeDivs();

    CLOCK_InitOsc0(&g_defaultClockConfigRun.oscConfig);
    CLOCK_SetXtal0Freq(CPU_XTAL_CLK_HZ);

    CLOCK_BootToPeeMode(g_defaultClockConfigRun.mcgConfig.oscsel, kMCG_PllClkSelPll0,
        &g_defaultClockConfigRun.mcgConfig.pll0Config);

    CLOCK_SetInternalRefClkConfig(g_defaultClockConfigRun.mcgConfig.irclkEnableMode,
        g_defaultClockConfigRun.mcgConfig.ircs, g_defaultClockConfigRun.mcgConfig.fcrdiv);

    CLOCK_SetSimConfig(&g_defaultClockConfigRun.simConfig);

    SystemCoreClockUpdate();

    /*
     * pitConfig.enableRunInDebug = false;
     */
    PIT_GetDefaultConfig(&pitConfig);

    /* Init pit module */
    PIT_Init(PIT, &pitConfig);

#ifdef DEBUG

    /* Initialize LPUART4 pins below used to Print */
    /* Ungate the port clock */
    CLOCK_EnableClock(kCLOCK_PortC);
    /* Affects PORTC_PCR14 register */
    PORT_SetPinMux(PORTC, 14U, kPORT_MuxAlt3);
    /* Affects PORTC_PCR15 register */
    PORT_SetPinMux(PORTC, 15U, kPORT_MuxAlt3);

    /* SIM_SOPT2[27:26]:
     *  00: Clock Disabled
     *  01: MCGFLLCLK, or MCGPLLCLK, or IRC48M
     *  10: OSCERCLK
     *  11: MCGIRCCLK
     */
    CLOCK_SetLpuartClock(2);

    uartClkSrcFreq = KINETIS_K82_DEBUG_UART_CLK_FREQ;

    DbgConsole_Init(KINETIS_K82_DEBUG_UART_INSTANCE, KINETIS_K82_DEBUG_UART_BAUDRATE, KINETIS_K82_DEBUG_UART_TYPE, uartClkSrcFreq);
#endif /* DEBUG */
}
#endif /* PHDRIVER_KINETIS_K82 */

#ifdef PH_PLATFORM_HAS_ICFRONTEND
/**
* This function will initialize Host Controller interfaced with NXP Reader IC's.
* Any initialization which is not generic across Platforms, should be done here.
* Note: For NXP NFC Controllers HOST initialization is not required.
*/
void phApp_CPU_Init(void)
{
#if defined PHDRIVER_KINETIS_K82
    phApp_K82_Init();
#elif defined(PHDRIVER_LPC1769) && defined(__CC_ARM)
    SystemCoreClock =  (( unsigned long ) 96000000);
#elif defined(PH_OSAL_LINUX) && defined(NXPBUILD__PHHAL_HW_PN5190)
    phStatus_t  status;
    status = PiGpio_OpenIrq();
    if ((status & PH_ERR_MASK) != PH_ERR_SUCCESS)
    {
        DEBUG_PRINTF("\n PiGpio_OpenIrq failed \n");
        DEBUG_PRINTF("\n Couldn't open PN5190 Kernel IRQ Driver.\n Halting here!!FIX IT!!\n");
        while(1);
    }
#else
    /* In case of LPC series, startup file takes care of initializing clock and ports.
     * No initialization is required in Linux environment. */
#endif
}
#endif /* PH_PLATFORM_HAS_ICFRONTEND */

/**
* This function will initialize Reader LIbrary Component
*/
phStatus_t phApp_Comp_Init(void * pDiscLoopParams)
{
    phStatus_t wStatus = PH_ERR_SUCCESS;
#if defined(NXPBUILD__PHPAL_I18092MPI_SW) || defined(NXPBUILD__PHPAL_I18092MT_SW) || \
    defined(NXPBUILD__PHAC_DISCLOOP_TYPEA_P2P_TAGS) || defined(NXPBUILD__PHAC_DISCLOOP_TYPEA_P2P_ACTIVE) || \
    defined(NXPBUILD__PHAC_DISCLOOP_TYPEA_I3P4_TAGS) || defined(NXPBUILD__PHAC_DISCLOOP_TYPEF_P2P_TAGS) || \
    defined(NXPBUILD__PHAC_DISCLOOP_TYPEF212_P2P_ACTIVE) || defined(NXPBUILD__PHAC_DISCLOOP_TYPEF424_P2P_ACTIVE)

    phacDiscLoop_Sw_DataParams_t * pDiscLoop = (phacDiscLoop_Sw_DataParams_t *)pDiscLoopParams;
#endif

/* Initialize the LLCP component */
#ifdef NXPBUILD__PHLN_LLCP_SW
    slnLlcp.sLocalLMParams.wMiu = 0x00; /* 128 bytes only */
    slnLlcp.sLocalLMParams.wWks = 0x11; /* SNEP & LLCP */
    slnLlcp.sLocalLMParams.bLto = 100; /* Maximum LTO */
    slnLlcp.sLocalLMParams.bOpt = 0x02;
    slnLlcp.sLocalLMParams.bAvailableTlv = PHLN_LLCP_TLV_MIUX_MASK | PHLN_LLCP_TLV_WKS_MASK |
        PHLN_LLCP_TLV_LTO_MASK | PHLN_LLCP_TLV_OPT_MASK;

    wStatus = phlnLlcp_Sw_Init(
        &slnLlcp,
        sizeof(phlnLlcp_Sw_DataParams_t),
        aLLCPGeneralBytes,
        &bLLCPGBLength);
#endif /* NXPBUILD__PHLN_LLCP_SW */

#ifdef NXPBUILD__PHAC_DISCLOOP_SW
#if defined(NXPBUILD__PHPAL_I18092MPI_SW) || defined(NXPBUILD__PHPAL_I18092MT_SW)
    /* Assign the GI for Type A */
    pDiscLoop->sTypeATargetInfo.sTypeA_P2P.pGi       = (uint8_t *)aLLCPGeneralBytes;
    pDiscLoop->sTypeATargetInfo.sTypeA_P2P.bGiLength = bLLCPGBLength;
    /* Assign the GI for Type F */
    pDiscLoop->sTypeFTargetInfo.sTypeF_P2P.pGi       = (uint8_t *)aLLCPGeneralBytes;
    pDiscLoop->sTypeFTargetInfo.sTypeF_P2P.bGiLength = bLLCPGBLength;
#endif

#if defined(NXPBUILD__PHAC_DISCLOOP_TYPEA_P2P_TAGS) || defined(NXPBUILD__PHAC_DISCLOOP_TYPEA_P2P_ACTIVE)
    /* Assign ATR response for Type A */
    pDiscLoop->sTypeATargetInfo.sTypeA_P2P.pAtrRes   = aResponseHolder;
#endif
#if defined(NXPBUILD__PHAC_DISCLOOP_TYPEF_P2P_TAGS) ||  defined(NXPBUILD__PHAC_DISCLOOP_TYPEF212_P2P_ACTIVE) || \
    defined(NXPBUILD__PHAC_DISCLOOP_TYPEF424_P2P_ACTIVE)
    /* Assign ATR response for Type F */
    pDiscLoop->sTypeFTargetInfo.sTypeF_P2P.pAtrRes   = aResponseHolder;
#endif
#ifdef NXPBUILD__PHAC_DISCLOOP_TYPEA_I3P4_TAGS
    /* Assign ATS buffer for Type A */
    pDiscLoop->sTypeATargetInfo.sTypeA_I3P4.pAts     = aResponseHolder;
#endif /* NXPBUILD__PHAC_DISCLOOP_TYPEA_I3P4_TAGS */
#endif /* NXPBUILD__PHAC_DISCLOOP_SW */
	pHal =phNfcLib_GetDataParams(PH_COMP_HAL);
    return wStatus;
}

#define DPC_MAX_CURRENT				270
#define TXLDO_VDDPA_MAX_VAL		0x1D		//4.4V

#define DCDC_PWR_CONFIG				0x0000
#define DCDC_CONFIG					0x0001
#define TX_LDO_CONFIG				0x0002
#define TX_LDO_VDDPA_HIGH			0x0006
#define TX_LDO_VDDPA_LOW			0x0007
#define TX_LDO_VDDPA_MAX_RDR		0x0008
#define TX_LDO_VDDPA_MAX_CARD		0x0009
#define DPC_CONFIG					0x0076
#define DPC_TARGET_CURRENT			0x0077

static const uint8_t dpc_enable_power_configs[10] = {
	[DCDC_PWR_CONFIG] = 0x01,
	[TX_LDO_VDDPA_HIGH] = 0x00,
	[TX_LDO_VDDPA_MAX_RDR] = 0x2A,
};
//打印DPC配置
static void ph_configure_print_dpc(void){
	uint8_t dpc_configs[32];
	phhalHw_Pn5190_DataParams_t * pDataParams = phNfcLib_GetDataParams(PH_COMP_HAL);
	phStatus_t statusTmp;
	uint16_t start = 0x76;
	uint16_t end = 0x8A;
	uint16_t offset;
    //读取DPC配置
	statusTmp = phhalHw_Pn5190_Instr_ReadE2Prom(pDataParams, start , dpc_configs, end-start);
	if( PH_ERR_SUCCESS != (statusTmp & PH_ERR_MASK )){
		DEBUG_PRINTF("\n dpc_config read fail: %04X \n", statusTmp);
		return ;
	}
	DEBUG_PRINTF("\n");
	for(offset = start; offset < end; offset++){
		DEBUG_PRINTF("offset=%X, value= %02X \n", offset, dpc_configs[offset-start]);
	}
    //读取DPC电流表
    uint32_t dpc_table[42];
    statusTmp = phhalHw_Pn5190_Instr_ReadE2Prom(pDataParams, 0x8B, (uint8_t*)dpc_table, sizeof(dpc_table));
	if( PH_ERR_SUCCESS!= (statusTmp & PH_ERR_MASK )){
		DEBUG_PRINTF("\n dpc_table read fail: %04X \n", statusTmp);
		return ;	
	}
	DEBUG_PRINTF("\n");
	for(offset = 0; offset < 42; offset++){
		DEBUG_PRINTF("offset=%04X, value= %08X \n", (offset * 4 + 0x8B), dpc_table[offset]);
	}
}

//打印版本信息
static void ph_configure_print_version(void){
	phhalHw_Pn5190_DataParams_t * pDataParams = phNfcLib_GetDataParams(PH_COMP_HAL);
	phStatus_t statusTmp;
    phhalHw_Pn5190_Version_t version;
    statusTmp = phhalHw_Pn5190_Instr_GetVersion(pDataParams, &version);
	if( PH_ERR_SUCCESS!= (statusTmp & PH_ERR_MASK )){
		DEBUG_PRINTF("\n version read fail: %04X \n", statusTmp);
		return ;
	}
	DEBUG_PRINTF("\n");
	DEBUG_PRINTF(" Hw_Version: %02X \n ROM_Version: %02x \n FW_Version: %04X", 
        version.bHw_Version, version.bROM_Version, version.wFW_Version);
}

phStatus_t phApp_Configure_Power(void){
	phhalHw_Pn5190_DataParams_t * pDataParams = phNfcLib_GetDataParams(PH_COMP_HAL);

	phStatus_t statusTmp;
	/*
	配置DCDC电源。电路并没有使用DCDC，使用外部电源单独给TX_LDO供电。
	Configuration example 4: TX_LDO supplied independent from VBAT - no DC-DC
	VBAT is connected to VBATPWR.
	
	DCDC_PWR_CONFIG (0000h) - Enables/disables and configures the DC-DC according
	to the external supply connections.
	TX_LDO_CONFIG (address 0002h) - Enables/disables and configures the TX_LDO.
	TX_LDO_VDDPA_HIGH (address 0006h) - initial out voltage when DPC is used.
	TX_LDO_VDDPA_LOW (address 0007h) - lowest VDDPA when DPC is used.
	TX_LDO_VDDPA_MAX_RDR (address 0008h) - maximum voltage to be set in reader
	mode used by DPC.
	TX_LDO_VDDPA_MAX_CARD (address 0009h) - VDDPA maximum voltage to be set in
	card mode used by DPC.
	No specific registers are required to configure the pad supply (VDDIO) or the supply for
	the analog and digital blocks (VUP).
	*/
    ph_configure_print_version();
//	    ph_configure_print_dpc();
	uint8_t dpc_config = 0;
	statusTmp = phhalHw_Pn5190_Instr_ReadE2Prom(pDataParams, DPC_CONFIG , &dpc_config, sizeof(dpc_config));
	if( PH_ERR_SUCCESS != (statusTmp & PH_ERR_MASK )){
		DEBUG_PRINTF("\n dpc_config read fail: %04X \n", statusTmp);
		return statusTmp;
	}
	DEBUG_PRINTF("\n DPC_CONFIG: %02X \n", dpc_config);
#if 1
	//使能DPC
	if((dpc_config & 0x07) != 0x07){
		dpc_config = 0x77;
		statusTmp = phhalHw_Pn5190_Instr_WriteE2Prom(pDataParams, DPC_CONFIG, &dpc_config, 1);
		if( PH_ERR_SUCCESS != (statusTmp & PH_ERR_MASK )){
			return statusTmp;
		}
	}
#else
	if((dpc_config) != 0x70){
		dpc_config = 0x70;
		statusTmp = phhalHw_Pn5190_Instr_WriteE2Prom(pDataParams, DPC_CONFIG, &dpc_config, 1);
		if( PH_ERR_SUCCESS != (statusTmp & PH_ERR_MASK )){
			return statusTmp;
		}
	}

#endif 
	uint8_t update = 0;
	uint8_t configs[10];
	statusTmp = phhalHw_Pn5190_Instr_ReadE2Prom(pDataParams, DCDC_PWR_CONFIG , configs, sizeof(configs));
	if( PH_ERR_SUCCESS != (statusTmp & PH_ERR_MASK )){
		return statusTmp;
	}
	uint16_t dpc_tag_current;
	statusTmp = phhalHw_Pn5190_Instr_ReadE2Prom(pDataParams, DPC_TARGET_CURRENT , (uint8_t*)&dpc_tag_current, sizeof(dpc_tag_current));
	if( PH_ERR_SUCCESS != (statusTmp & PH_ERR_MASK )){
		return statusTmp;
	}
	DEBUG_PRINTF("\nDCDC_PWR_CONFIG: %02X \n", configs[DCDC_PWR_CONFIG]);
	DEBUG_PRINTF("DCDC_CONFIG: %02X \n", configs[DCDC_CONFIG]);
	// DEBUG_PRINTF("TX_LDO_CONFIG: %02X %02X %02X %02X\n", configs[TX_LDO_CONFIG],configs[TX_LDO_CONFIG+1],configs[TX_LDO_CONFIG+2],configs[TX_LDO_CONFIG+3]);
    DEBUG_PRINTF("TX_LDO_CONFIG: %08X \n", *(uint32_t*)&configs[TX_LDO_CONFIG]);
	DEBUG_PRINTF("TX_LDO_VDDPA_HIGH: %02X \n", configs[TX_LDO_VDDPA_HIGH]);
	DEBUG_PRINTF("TX_LDO_VDDPA_LOW: %02X \n", configs[TX_LDO_VDDPA_LOW]);
	DEBUG_PRINTF("TX_LDO_VDDPA_MAX_RDR: %02X \n", configs[TX_LDO_VDDPA_MAX_RDR]);
	DEBUG_PRINTF("TX_LDO_VDDPA_MAX_CARD: %02X \n", configs[TX_LDO_VDDPA_MAX_CARD]);
	DEBUG_PRINTF("DPC_TARGET_CURRENT: %d \n", dpc_tag_current);
#if 1
	uint8_t vup_input = configs[DCDC_PWR_CONFIG] & 0x1F;
	uint8_t dcdc = configs[DCDC_PWR_CONFIG]&((0x01 << 6)|(0x01 << 7));
	if(vup_input != 0x01 || dcdc != 0x00 ){
		configs[DCDC_PWR_CONFIG] = (0x01 << 5) | 0x01;
		update = 1;
	}
#endif
	
	if(update){
		statusTmp = phhalHw_Pn5190_Instr_WriteE2Prom(pDataParams, DCDC_PWR_CONFIG, &configs[DCDC_PWR_CONFIG], 1);
		if( PH_ERR_SUCCESS != (statusTmp & PH_ERR_MASK )){
			return statusTmp;
		}
	}

	uint8_t dcdc_config = configs[DCDC_CONFIG];
	dcdc_config &= ~((1 << 3)|(1 << 4));
	if(dcdc_config != configs[DCDC_CONFIG]){
		statusTmp = phhalHw_Pn5190_Instr_WriteE2Prom(pDataParams, DCDC_CONFIG, &dcdc_config, 1);
		if( PH_ERR_SUCCESS != (statusTmp & PH_ERR_MASK )){
			return statusTmp;
		}
	}
	//最大4.4V
	if(configs[TX_LDO_VDDPA_HIGH] != 0x00){
		configs[TX_LDO_VDDPA_HIGH] = 0x00;
		statusTmp = phhalHw_Pn5190_Instr_WriteE2Prom(pDataParams, TX_LDO_VDDPA_HIGH, &configs[TX_LDO_VDDPA_HIGH], 1);
		if( PH_ERR_SUCCESS != (statusTmp & PH_ERR_MASK )){
			return statusTmp;
		}
	}
	if(configs[TX_LDO_VDDPA_MAX_RDR] != TXLDO_VDDPA_MAX_VAL){
		configs[TX_LDO_VDDPA_MAX_RDR] = TXLDO_VDDPA_MAX_VAL;
		statusTmp = phhalHw_Pn5190_Instr_WriteE2Prom(pDataParams, TX_LDO_VDDPA_MAX_RDR, &configs[TX_LDO_VDDPA_MAX_RDR], 1);
		if( PH_ERR_SUCCESS != (statusTmp & PH_ERR_MASK )){
			return statusTmp;
		}
	}
	if(configs[TX_LDO_VDDPA_MAX_CARD] != TXLDO_VDDPA_MAX_VAL){
		configs[TX_LDO_VDDPA_MAX_CARD] = TXLDO_VDDPA_MAX_VAL;
		statusTmp = phhalHw_Pn5190_Instr_WriteE2Prom(pDataParams, TX_LDO_VDDPA_MAX_CARD, &configs[TX_LDO_VDDPA_MAX_CARD], 1);
		if( PH_ERR_SUCCESS != (statusTmp & PH_ERR_MASK )){
			return statusTmp;
		}
	}
	if(dpc_tag_current != DPC_MAX_CURRENT){
		dpc_tag_current = DPC_MAX_CURRENT;
		statusTmp = phhalHw_Pn5190_Instr_WriteE2Prom(pDataParams, DPC_TARGET_CURRENT, (uint8_t*)&dpc_tag_current, sizeof(dpc_tag_current));
		if( PH_ERR_SUCCESS != (statusTmp & PH_ERR_MASK )){
			return statusTmp;
		}
	}

	return statusTmp;
}

phStatus_t phApp_Configure_IRQ(void)
{
#ifdef PH_OSAL_LINUX
    phStatus_t  wStatus;
#endif /* PH_OSAL_LINUX */

#ifdef PH_PLATFORM_HAS_ICFRONTEND
#if !(defined(PH_OSAL_LINUX) && defined(NXPBUILD__PHHAL_HW_PN5190))
    phDriver_Pin_Config_t pinCfg;

    pinCfg.bOutputLogic = PH_DRIVER_SET_LOW;
    pinCfg.bPullSelect = PHDRIVER_PIN_IRQ_PULL_CFG;

    pinCfg.eInterruptConfig = PIN_IRQ_TRIGGER_TYPE;
    phDriver_PinConfig(PHDRIVER_PIN_IRQ, PH_DRIVER_PINFUNC_INTERRUPT, &pinCfg);
#endif

#ifdef PHDRIVER_GD32PN5190_BOARD
    NVIC_SetPriority(EINT_IRQn, EINT_PRIORITY);
    /* Enable interrupt in the NVIC */
    NVIC_ClearPendingIRQ(EINT_IRQn);
    NVIC_EnableIRQ(EINT_IRQn);
#endif

#ifdef PHDRIVER_LPC1769
    NVIC_SetPriority(EINT_IRQn, EINT_PRIORITY);
    /* Enable interrupt in the NVIC */
    NVIC_ClearPendingIRQ(EINT_IRQn);
    NVIC_EnableIRQ(EINT_IRQn);
#endif /* PHDRIVER_LPC1769 */

#ifdef PH_OSAL_LINUX

    gphPiThreadObj.pTaskName = (uint8_t *) "IrqPolling";
    gphPiThreadObj.pStackBuffer = NULL;
    gphPiThreadObj.priority = PI_IRQ_POLLING_TASK_PRIO;
    gphPiThreadObj.stackSizeInNum = PI_IRQ_POLLING_TASK_STACK;
    PH_CHECK_SUCCESS_FCT(wStatus, phOsal_ThreadCreate(&gphPiThreadObj.ThreadHandle, &gphPiThreadObj,
        &phExample_IrqPolling, NULL));

#endif /* PH_OSAL_LINUX */

#ifdef PHDRIVER_KINETIS_K82
    NVIC_SetPriority(EINT_IRQn, EINT_PRIORITY);
    NVIC_ClearPendingIRQ(EINT_IRQn);
    EnableIRQ(EINT_IRQn);
#endif /* PHDRIVER_KINETIS_K82 */

#endif /* #ifdef PH_PLATFORM_HAS_ICFRONTEND */

    return PH_ERR_SUCCESS;
}

#ifdef PH_OSAL_LINUX
/*
 * \brief: The purpose of this Thread is to detect RF signal from an External Peer .
 */
static void phExample_IrqPolling(void* param)
{
    uint8_t bgpioVal = 0;
    uint8_t bhighOrLow = 0;

#if defined(NXPBUILD__PHHAL_HW_RC663) || defined(NXPBUILD__PHHAL_HW_PN5180)
    if(PIN_IRQ_TRIGGER_TYPE ==  PH_DRIVER_INTERRUPT_RISINGEDGE)
    {
        bhighOrLow = 1;
    }

    while(PiGpio_read(PHDRIVER_PIN_IRQ, &bgpioVal) != PH_ERR_SUCCESS)
    {
        PiGpio_unexport(PHDRIVER_PIN_IRQ);
        PiGpio_export(PHDRIVER_PIN_IRQ);
        PiGpio_set_direction(PHDRIVER_PIN_IRQ, false);

        if(PIN_IRQ_TRIGGER_TYPE ==  PH_DRIVER_INTERRUPT_RISINGEDGE)
        {
            PiGpio_set_edge(PHDRIVER_PIN_IRQ, true, false);
        }
        else
        {
            PiGpio_set_edge(PHDRIVER_PIN_IRQ, false, true);
        }
    }

    /* Initial status: If pin is already Active, post an event. */
    if(bgpioVal == bhighOrLow)
    {
        CLIF_IRQHandler();
    }
#endif

    while(1)
    {
        /* Block forever for Raising Edge in PHDRIVER_PIN_IRQ. */
#if defined(NXPBUILD__PHHAL_HW_RC663) || defined(NXPBUILD__PHHAL_HW_PN5180)
        if(PiGpio_poll(PHDRIVER_PIN_IRQ, bhighOrLow, -1) == PH_ERR_SUCCESS)
#elif defined(NXPBUILD__PHHAL_HW_PN5190)
        if(PiGpio_Irq() == PH_ERR_SUCCESS)
#endif
        {
            CLIF_IRQHandler();
        }
        else
        {
            PiGpio_unexport(PHDRIVER_PIN_IRQ);

            PiGpio_export(PHDRIVER_PIN_IRQ);

            PiGpio_set_direction(PHDRIVER_PIN_IRQ, false);

            if(PIN_IRQ_TRIGGER_TYPE ==  PH_DRIVER_INTERRUPT_RISINGEDGE)
            {
                PiGpio_set_edge(PHDRIVER_PIN_IRQ, true, false);
            }
            else
            {
                PiGpio_set_edge(PHDRIVER_PIN_IRQ, false, true);
            }
        }


    }
}
#endif /* PH_OSAL_LINUX */

void phApp_Led_Init( void )
{
#if 0
    phDriver_Pin_Config_t pinCfg;

    pinCfg.bPullSelect = PH_DRIVER_PULL_UP;
    pinCfg.bOutputLogic = PH_DRIVER_SET_LOW;
#ifndef PH_OSAL_LINUX
    phDriver_PinConfig(PHDRIVER_PIN_RLED, PH_DRIVER_PINFUNC_OUTPUT, &pinCfg);
#endif
    pinCfg.bPullSelect = PH_DRIVER_PULL_UP;
    pinCfg.bOutputLogic = PH_DRIVER_SET_LOW;
#ifndef PH_OSAL_LINUX
    phDriver_PinConfig(PHDRIVER_PIN_GLED, PH_DRIVER_PINFUNC_OUTPUT, &pinCfg);
#endif
    pinCfg.bPullSelect = PH_DRIVER_PULL_UP;
    pinCfg.bOutputLogic = PH_DRIVER_SET_LOW;
#ifndef PH_OSAL_LINUX
    phDriver_PinConfig(PHDRIVER_PIN_BLED, PH_DRIVER_PINFUNC_OUTPUT, &pinCfg);
#endif
    pinCfg.bPullSelect = PH_DRIVER_PULL_UP;
    pinCfg.bOutputLogic = PH_DRIVER_SET_LOW;
#ifndef PH_OSAL_LINUX
    phDriver_PinConfig(PHDRIVER_PIN_OLED, PH_DRIVER_PINFUNC_OUTPUT, &pinCfg);
#endif
    /* make all the LEDs OFF */
#ifndef PH_OSAL_LINUX
    phApp_Led_Off(PHDRIVER_PIN_RLED);
    phApp_Led_Off(PHDRIVER_PIN_BLED);
    phApp_Led_Off(PHDRIVER_PIN_GLED);
    phApp_Led_Off(PHDRIVER_PIN_OLED);
#endif
    return;
#endif 
}


void phApp_Led_On( uint32_t dwPinNumber )
{
    phDriver_PinWrite(dwPinNumber, PH_DRIVER_SET_LOW);
    return;
}

void phApp_Led_Off( uint32_t dwPinNumber )
{
    phDriver_PinWrite(dwPinNumber, PH_DRIVER_SET_HIGH);
    return;
}

/******************************************************************************
**                            End Of File
******************************************************************************/
